package com.zifeng.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zifeng.dao.BlockDao;
import com.zifeng.dao.TransactionDao;
import com.zifeng.pojo.Block;
import com.zifeng.pojo.Transaction;
import lombok.Data;
import org.java_websocket.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 区块链区块结构体：
 *   1.区块链
 *   2.业务信息链
 *   3.p2p网络节点列表
 */
@ConfigurationProperties(prefix = "block")
@Component
@Data
public class BlockCache {

	@Autowired
	private BlockDao blockDao;

	@Autowired
	private TransactionDao transactionDao;
	
	/**
	 * 当前节点的socket对象
	 */
	private List<WebSocket> socketsList = new CopyOnWriteArrayList<WebSocket>();
	
	/**
	 * 挖矿的难度系数
	 */
	@Value("${block.difficulty}")
	private int difficulty;
	
	/**
	 * 当前节点p2pserver端口号
	 */
	@Value("${block.p2pport}")
	private int p2pPort;
	
	/**
	 * 要连接的节点地址
	 */
	@Value("${block.address}")
	private String address;
	
	/**
	 * 获取最新的区块，即当前链上最后一个区块
	 * 
	 * @return
	 */
	public Block getLatestBlock() {
		QueryWrapper<Block> wrapper = new QueryWrapper<>();
		wrapper.orderByDesc("block_timestamp").last("limit 1");
		Block latestBlock = blockDao.selectOne(wrapper);
		latestBlock.setTransactions(getPackedTransactions(latestBlock.getBlockIndex()));
		return latestBlock;
	}

	/**
	 * 当前节点的区块链结构
	 */
	public List<Block> getBlockChain() {
		List<Block> blocks = blockDao.selectList(null);
		return blocks;
	}

	public List<Transaction> getPackedTransactions() {
		List<Transaction> transactions = transactionDao.selectList(null);
		return transactions;
	}

	/**
	 * 已打包保存的业务数据集合
	 */
	public List<Transaction> getPackedTransactions(Long blockId) {
		QueryWrapper<Transaction> wrapper = new QueryWrapper<>();
		wrapper.eq("block_id", blockId);
		List<Transaction> transactions = transactionDao.selectList(wrapper);
		return transactions;
	}

}
